<!--
 * @LastEditors: yuSeen
 * @LastEditTime: 2021-12-31 16:26:16
-->
<template>
    <!-- 播放栏左侧部分 -->
    <div class="absolute left-0 w-64 px-3 overflow-hidden h-playBar-height text-common-text-color">
        <!-- 菜单 -->
        <div
            class="menus flex-c"
            :class="{ 'translate1': playStore.inPlayPage }"
            @click="toggleSongDetail()"
        >
            <div class="w-12 flex-c-c" title="收起音乐详情页">
                <SvgIcon name="arrow-tb" size="18" class="transform rotate-180 hoverArrow" />
            </div>
            <div class="menulist flex-b-c" style="width: 184px;">
                <div class="menuItem" title="喜欢">
                    <SvgIcon name="love" size="20" />
                </div>
                <div class="menuItem" title="收藏">
                    <SvgIcon name="add-collect-icon" />
                </div>
                <div class="menuItem" title="下载">
                    <SvgIcon name="download-icon" />
                </div>
                <div class="menuItem" title="分享">
                    <SvgIcon name="share-icon" />
                </div>
            </div>
        </div>

        <!-- 歌曲信息 -->
        <div
            class="song flex-c"
            :class="{ 'translate2': playStore.inPlayPage }"
        >
            <div class="cover flex-c-c" @click="toggleSongDetail()" title="展开音乐详情页">
                <img class="trans" :src="playStore.cover" alt="歌曲封面" />
                <SvgIcon name="arrow-tb" size="23" fill="#fff" class="hoverArrow" />
            </div>
            <div class="ml-3 info" style="width: 172px;">
                <!-- 歌名 -->
                <div class="relative flex-c">
                    <div
                        ref="nameBoxDom"
                        style="max-width: 149px;"
                        class="flex overflow-x-scroll"
                        @mouseenter="preSetScrollAnimation"
                        @mouseleave="destoryScrollAnimation"
                    >
                        <p
                            ref="nameDom"
                            class="inline-block mb-0 transform translate-x-0 whitespace-nowrap"
                            v-html="playStore.name"
                        ></p>
                    </div>
                    <SvgIcon name="love" size="23" />
                </div>
                <!-- 歌手 -->
                <div class="text-12 text-sub-text-color trans">{{ playStore.singer || '未知艺术家' }}</div>
            </div>
        </div>
    </div>
</template>

<script lang='ts' setup>
import { throttle } from 'lodash'
import { usePlayStore } from '@/store/play'
import { useDom } from '@/hooks/dom/useDom'
import { ref } from 'vue'
import SvgIcon from '../svgIcon/svgIcon.vue'

const playStore = usePlayStore()

// 切换进入、离开播放详情页
const toggleSongDetail = throttle(function (flag?: boolean) {
    playStore.toggleInPlayPage(flag)
}, 600)

// 放置歌曲名称的盒子dom
const nameBoxDom = ref<HTMLElement>(null as unknown as HTMLElement)
// 放置歌曲名称的dom
const nameDom = ref<HTMLElement>(null as unknown as HTMLElement)
// 动画是否进行中，避免同时开启多个动画
let inAnimation = false

// 获取名称dom宽度，用于设置动画，由于overflow：hidden之后无法获取内部的完整宽度，故只能允许其生成滚动条并使用scrollWidth来计算宽度
const getNameWidth = () => {
    const width = nameDom.value.clientWidth
    if (width === 144) {
        return nameBoxDom.value.scrollWidth
    }
    return width
}

// 动画ID,用于关闭动画
let animateId: number;

const { getTranslateX } = useDom()

// 鼠标进入歌名，预备开启动画
const preSetScrollAnimation = () => {
    if (inAnimation) return;
    inAnimation = true
    setScrollAnimation()
}

//设置滚动动画, target为目标停止坐标
const setScrollAnimation = (target?: number | MouseEvent) => {
    const width = getNameWidth()
    if (width <= 144) return;    //宽度小于等于144则无需设置动画
    const left = getTranslateX(nameDom.value)    
    // 若设置了停止坐标且当前偏移量等于目标位置，则关闭动画
    if (typeof target === 'number' && target === Math.abs(left)) {
        cancelAnimationFrame(animateId)
        return inAnimation = false
    }
    nameDom.value.style.transform = width >= Math.abs(left) ? `translateX(${left - 1}px)` : `translateX(${width}px)`
    animateId = requestAnimationFrame(() => setScrollAnimation(target))
}

// 鼠标离开，使其恢复到偏移量为0的位置并结束动画
const destoryScrollAnimation = () => {
    cancelAnimationFrame(animateId)
    setScrollAnimation(0)
}
</script>

<style scoped lang='scss'>
.menus {
    @apply w-full h-full transition ease-in-out duration-700;
    transform: translateY(-$playBar-height)
}
.song {
    @apply w-full h-full transition ease-in-out duration-700;
    transform: translateY(-$playBar-height)
}

.menuItem {
    @apply flex justify-center items-center w-9 h-9 border rounded-full border-sub-border-color hover:bg-active-bg-color;
    transition-property: border-color;
    transition-duration: 300ms;
}
.cover {
    @apply relative w-12 h-12 overflow-hidden border rounded border-sub-border-color cursor-pointer duration-300;
    transition-property: border-color;
    &:hover {
        img {
            filter: blur(2px);
        }
        .hoverArrow {
            visibility: visible;
        }
    }
    .hoverArrow {
        @apply absolute invisible;
    }
}
.translate1 {
    transform: translateY(0);
}
.translate2 {
    transform: translateY(200%);
}

// 隐藏滚动条
::-webkit-scrollbar {
    width: 0px;
    height: 0px;
}
</style>